import { debounce } from 'lodash'
import { HeafListMixin, HeafUtils } from 'hyida-element-framework'

// 布局相关的列属性
const COLUMN_LAYOUT_ATTRS = ['filters', 'hide', 'fixed', 'width', 'sortable']

const DEFAULT_DEBOUNCE_MS = 500
const DEFAULT_DEBOUNCE_OPTIONS = { leading: true, trailing: false }

/**
 * 过滤字典翻译字段
 */
const filterParams = (form) => {
  let data = form
  for (let o in data) {
    if (o.indexOf('$') !== -1) delete data[o]
  }
  return data
}

export default {
  ...HeafListMixin,
  // 如果默认的行为不足以支撑您的项目，请在此扩展或者覆盖它
  data() {
    const ret = HeafListMixin.data()

    ret.tableOption.searchSpan = 8
    ret.tableOption.searchMenuSpan = 8
    ret.tableOption.labelSuffix = ' ' // 标题后缀, 默认为空。注意这里写空字符串会不生效，只能写成空格来表示没有
    ret.columnDefaults = {} // 默认数据
    ret.defaultsLoaded = false // 默认数据是否已加载
    ret.tableOption.columnSort = true // 支持表头拖动排序
    return ret
  },
  watch: {
    ...(HeafListMixin.watch || {}),
    columnDefaults: {
      handler(val) {
        if (!this.defaultsLoaded) {
          console.log('ignore change of concerned before defaultsLoaded', this.defaultsLoaded)
          return
        }
        this.saveColumnLayoutDefaults(val)
      },
      deep: true,
      immediate: true,
    },
  },
  created() {
    this.loadColumnLayoutDefaults()
  },
  methods: {
    ...HeafListMixin.methods,
    // 分页列表
    loadListData: debounce(
      async function (page, params) {
        try {
          this.tableLoading = true
          const listParams = Object.assign(
            {
              pageNo: page.currentPage,
              pageSize: page.pageSize,
            },
            this.searchForm,
            params
          )
          const { success, data } = await this.listApi(listParams)
          if (success) {
            this.tableLoading = false
            this.tableData = ((data && data.listObject) || []).map(this.listMapFunc)
            this.page.total = data.itemCount
            // FIX BUG: 多选没有及时清除 BELOW
            if (this.tableOption.selection) {
              // 多选列表
              if (this.$refs.crud && this.$refs.crud.selectClear) {
                this.$refs.crud && this.$refs.crud.selectClear()
              }
              if (this.$refs.crud && this.$refs.crud.clearSelection) {
                this.$refs.crud && this.$refs.crud.clearSelection()
              }
            }
            // FIX BUG: 多选没有及时清除 ABOVE
          }
        } catch (err) {
          console.log(err)
          this.tableLoading = false
        }
      },
      DEFAULT_DEBOUNCE_MS,
      DEFAULT_DEBOUNCE_OPTIONS
    ),

    // 新建
    onRowSave: debounce(
      async function (row, done, loading) {
        try {
          // 下面这一行不使用row的原因在于BUG#80901 http://pm.cosmoplat.com/index.php?m=bug&f=view&bugID=80901
          const params = this.editMapFunc(filterParams(this.form))
          const { success, message } = await this.createApi(params)
          if (success) {
            this.$message.success('新增成功')
            this.onRefresh()
            done()
          } else {
            this.$message.error(message)
            loading()
          }
        } catch (error) {
          console.log(error)
          this.$message.error('新增失败')
          loading()
        }
      },
      DEFAULT_DEBOUNCE_MS,
      DEFAULT_DEBOUNCE_OPTIONS
    ),
    // 编辑
    onRowUpdate: debounce(
      async function (row, index, done, loading) {
        try {
          // 下面这一行不使用row的原因在于BUG#80901 http://pm.cosmoplat.com/index.php?m=bug&f=view&bugID=80901
          const params = this.editMapFunc(filterParams(this.form))
          const { success, message } = await this.updateApi(params)
          if (success) {
            this.$message.success('编辑成功')
            this.onRefresh()
            done()
          } else {
            this.$message.error(message)
            loading()
          }
        } catch (error) {
          console.log(error)
          this.$message.error('编辑失败')
          loading()
        }
      },
      DEFAULT_DEBOUNCE_MS,
      DEFAULT_DEBOUNCE_OPTIONS
    ),
    // 批量删除
    onBatchDeleteClick: debounce(
      async function () {
        const length = (this.selection || []).length
        if (length < 0) {
          this.$message.warning('选中后才能批量删除')
          return
        }

        try {
          await this.$confirm(`确定删除选中的${length}项吗?`, {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
          })
        } catch (error) {
          console.log('取消')
          return
        }

        try {
          const { success, message } = await this.batchDeleteApi(this.selection)
          if (success) {
            this.$message.success('批量删除成功')
            /* Fix: BUG# 当最后一页数据全部批量删除时，删除后界面内容为空 luoyongbing 2023-02-01 below */
            if (
              length >= (this.page.total % this.page.pageSize || this.page.pageSize) && // 删除全部数据
              this.page.pageSize * this.page.currentPage >= this.page.total && // 在最后一页
              this.page.currentPage > 1 // 不在第一页
            ) {
              this.page.currentPage -= 1
            }
            /* Fix: BUG# 当最后一页数据全部批量删除时，删除后界面内容为空 luoyongbing 2023-02-01 above */
            this.onRefresh()
          } else {
            this.$message.error(message)
          }
        } catch (error) {
          this.$message.success('批量删除失败')
        }
      },
      DEFAULT_DEBOUNCE_MS,
      DEFAULT_DEBOUNCE_OPTIONS
    ),

    // 删除
    onRowDelete: debounce(
      async function (form, index) {
        try {
          await this.$confirm('确定删除吗?', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
          })
        } catch (error) {
          console.log('取消')
          return
        }

        try {
          const { success, message } = await this.deleteApi(form)
          if (success) {
            this.$message.success('删除成功')
            /* Fix: BUG# 60906 当最后一页只有一条数据时，删除后界面内容为空 luoyongbing 2022-06-02 below */
            if (
              this.page.total % this.page.pageSize === 1 && // 最后一页只有一条数据
              this.page.pageSize * this.page.currentPage > this.page.total && // 在最后一页
              this.page.currentPage > 1 // 不在第一页
            ) {
              this.page.currentPage -= 1
            }
            /* Fix: BUG# 60906 当最后一页只有一条数据时，删除后界面内容为空 luoyongbing 2022-06-02 above */
            this.onRefresh()
          } else {
            this.$message.error(message)
          }
        } catch (error) {
          console.log(error)
          this.$message.error('删除失败')
        }
      },
      DEFAULT_DEBOUNCE_MS,
      DEFAULT_DEBOUNCE_OPTIONS
    ),
    /**
     * 获取列布局默认值的KEY值，用于存到localStorage
     * @returns KEY值
     */
    getColumnLayoutDefaultsKey() {
      const key = 'defaults_of_' + this.$route.path.replace(/\//g, '_')
      return key
    },
    /**
     * 保存列布局属性
     * @param {*} val
     */
    saveColumnLayoutDefaults(val) {
      const concerned = {}
      for (const columnKey in val) {
        for (const attr in val[columnKey]) {
          if (COLUMN_LAYOUT_ATTRS.includes(attr)) {
            if (!concerned[columnKey]) {
              concerned[columnKey] = {}
            }
            concerned[columnKey][attr] = val[columnKey][attr]
          }
        }
      }

      // console.log('saveColumnLayoutDefaults', concerned)
      const key = this.getColumnLayoutDefaultsKey()
      HeafUtils.storageCache.setItem(key, concerned, 60 * 60 * 24 * 30) // 默认存30天, 每次进页面会刷新一次
    },
    /**
     * 加载列布局属性
     */
    loadColumnLayoutDefaults() {
      const key = this.getColumnLayoutDefaultsKey()
      const concerned = HeafUtils.storageCache.getItem(key)
      if (!concerned) {
        this.defaultsLoaded = true
        return
      }

      // console.log('loadColumnLayoutDefaults', concerned)
      for (const columnKey in concerned) {
        const column = this.findObject(this.tableOption.column, columnKey)
        if (!column) {
          console.log('igonre loaded Column Of', columnKey)
          continue
        }
        for (const attr in concerned[columnKey]) {
          column[attr] = concerned[columnKey][attr]
        }
      }
      this.defaultsLoaded = true
    },
  },
}
